/**
 * 
 */
package com.xbang.attendance.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.xbang.attendance.entity.Sign.Actioninfo;
import com.xbang.attendance.entity.companygps.companyGps;
import com.xbang.attendance.entity.legworktimes.LegworkTimes;
import com.xbang.attendance.service.AnalyseDataService;
import com.xbang.attendance.utils.Constants.QDConstants;
import com.xbang.core.service.impl.BaseServiceImpl;

/**
 * @author david
 * 
 */
public class AnalyseDataServiceImpl extends BaseServiceImpl implements AnalyseDataService {

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xbang.attendance.service.AnalyseDataService#initialOriDatas(java.
	 * util.List)
	 */
	public List<Map<String, List<Actioninfo>>> initialOriDatas(List<? extends Object> oriDatas) throws Exception {

		List<Actioninfo> actions = new ArrayList<Actioninfo>();
		actions.addAll((Collection<? extends Actioninfo>) oriDatas);

		Collections.sort(actions, new Comparator<Actioninfo>() {
			public int compare(Actioninfo source, Actioninfo indent) {
				return (source.getUserId().compareTo(indent.getUserId()));
			}

		});

		List<Map<String, List<Actioninfo>>> results = new ArrayList<Map<String, List<Actioninfo>>>();
		
		
		for (Actioninfo action : actions) {

			if (results.isEmpty()) {
				String key = action.getUserId();
				Map<String, List<Actioninfo>> tmpMap_ = null;
				if(results.size()==0){
					tmpMap_=results.get(0);
				}else{
					
					tmpMap_ = results.get(results.size() - 1);
				}
			//	Map<String, List<Actioninfo>> tmpMap_ = results.get(results.size() - 1);
				if (tmpMap_.containsKey(key)){
					tmpMap_.get(key).add(action);
				} else {
					Map<String, List<Actioninfo>> tmpMap__ = new HashMap<String, List<Actioninfo>>();
					List<Actioninfo> tmpLists = new ArrayList<Actioninfo>();
					tmpLists.add(action);
					tmpMap__.put(key, tmpLists);
					results.add(tmpMap__);
				}
				
				
			} else {
				String key = action.getUserId();
				Map<String, List<Actioninfo>> tmpMap__ = new HashMap<String, List<Actioninfo>>();
				List<Actioninfo> tmpLists = new ArrayList<Actioninfo>();
				tmpLists.add(action);
				tmpMap__.put(key, tmpLists);
				results.add(tmpMap__);
			}
		}

		return results;
	}

	/*
	 * 返回原始数据列表
	 * 
	 * @see
	 * com.xbang.attendance.service.AnalyseDataService#loadOriDatas(java.util
	 * .Map)
	 */
	public List<Actioninfo> loadOriDatas(List<Map> listmap) throws Exception {
        Map parametersmap = new HashMap<String, List<Actioninfo>>();
		List<Actioninfo> actions = new ArrayList<Actioninfo>();		 
		 for(Map parameters :listmap){
			  Iterator it = parameters.keySet().iterator();
			  Actioninfo actioninfo = new Actioninfo();	 		  
		            actioninfo.setActionSubType(datatoString("action_sub_type",parameters));
		            actioninfo.setActionType(datatoString("action_type",parameters));
		            actioninfo.setAction_desc(datatoString("action_desc",parameters)) ;
		            actioninfo.setAddress(datatoString("address", parameters));
		            actioninfo.setAppVersion(datatoString("app_version", parameters));
		            actioninfo.setDeviceId(datatoString("device_id", parameters));
		            actioninfo.setDeviceType(datatoString("device_type", parameters));
		            actioninfo.setDistance(datatoString("distance", parameters));
		            actioninfo.setGpsTime(datatoString("gps_time", parameters));
		            actioninfo.setGpsType(datatoString("gps_type", parameters));
		            actioninfo.setLateTime(datatoString("late_time", parameters));
		            actioninfo.setLocLatitude(datatoString("loc_latitude", parameters));
		            actioninfo.setLocLatitude(datatoString("loc_longtitude", parameters));
		            actioninfo.setServerTime(datatoString("server_time", parameters));
		            actioninfo.setSigninTime(datatoString("signin_time", parameters));
		            actioninfo.setUserId(datatoString("user_id", parameters));
		            actions.add(actioninfo);
		           // parametersmap.put(datatoString("user_id",parameters),actions); 
		    } 
  
		        return   actions ;  //一个用户   某天 所有action  actions 为 action 时间正需
	}
	
	public String datatoString(String str , Map<String, Object> parameters){
	String returnStr =	parameters.get(str)!=null?parameters.get(str).toString():"";
		return returnStr;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xbang.attendance.service.AnalyseDataService#analyseData(java.util
	 * .List)
	 */
	@SuppressWarnings("unchecked")
	public List<? extends Object> analyseData(String userId, List<? extends Object> oriDatas) throws Exception {

		// 记录最近有效地，未完成的公司考勤情况
		String companyAttendanceKey = "";
		// 记录最近有效地，未完成的外勤考勤情况
		String outAttendanceKey = "";
        boolean  outGo = false;
		Map<String, Actioninfo> normalActions = new HashMap<String, Actioninfo>(); //暂存action及 action的类型
		Map<String, Actioninfo> OutActions = new HashMap<String, Actioninfo>(); //暂存action及 action的类型

		List<Map<String, Actioninfo>> validateActions = new ArrayList<Map<String, Actioninfo>>();
		List<Map<String, Actioninfo>> tmpValidateAction = new ArrayList<Map<String, Actioninfo>>();

		for (Actioninfo action : (List<Actioninfo>) oriDatas) {
			// 类型
			String type =  action.getActionType();
			// 小类型
			String subType =action.getActionSubType();
			if (type.equals(QDConstants.COMPONY_ATTENDANCE_KEY)) { //如果公司考勤
				// 公司类型
				if (subType.equals(QDConstants.COMPONY_ATTENDANCE_LEFT_KEY)) { //如果 我来了
					// 我来了
					if(!companyAttendanceKey.equals(QDConstants.COMPONY_ATTENDANCE_LEFT_KEY)){ //如果 没有 我来了的状态

						companyAttendanceKey = QDConstants.COMPONY_ATTENDANCE_LEFT_KEY; 
						normalActions.put(companyAttendanceKey, action);   //存储我来了的action
					}
					
					if(companyAttendanceKey.equals(QDConstants.COMPONY_ATTENDANCE_RIGHT_KEY)){
						companyAttendanceKey = QDConstants.COMPONY_ATTENDANCE_LEFT_KEY; 
						normalActions.put(companyAttendanceKey, action);   //存储我来了的action
					}
			
				} else if (subType.equals(QDConstants.COMPONY_ATTENDANCE_RIGHT_KEY)) {   //如果 我走了
					// 我走了
					if (companyAttendanceKey.equals(QDConstants.COMPONY_ATTENDANCE_LEFT_KEY)) { //判断  有没有我来了的状态
						// 公司的成立,保存后，做初始化
						companyAttendanceKey = QDConstants.COMPONY_ATTENDANCE_RIGHT_KEY;
						Map<String, Actioninfo> tmpMaps = new HashMap<String, Actioninfo>();
						tmpMaps.put(QDConstants.COMPONY_ATTENDANCE_LEFT_KEY, normalActions.get(QDConstants.COMPONY_ATTENDANCE_LEFT_KEY));
						tmpMaps.put(subType, action);
						validateActions.add(tmpMaps); //存入一个完整的有效签到
						savelegworktimes(userId, validateActions);
						outAttendanceKey = "";   //我开工 清空
						OutActions.clear();
						OutActions =  new HashMap<String, Actioninfo>(); //外勤存值清空
						tmpValidateAction =  new ArrayList<Map<String, Actioninfo>>() ;
						// 清理
					}
				}
				
			} else if (type.equals(QDConstants.OUT_ATTENDANCE_KEY)) {  //外勤
				// 外勤类型
				if (subType.equals(QDConstants.OUT_ATTENDANCE_LEFT_KEY)) {  //我开工了					
					// 外勤，我开工了
					if(!outAttendanceKey.equals(QDConstants.OUT_ATTENDANCE_LEFT_KEY)){ //如果 没有 我开工 的状态
                     
						outAttendanceKey =QDConstants.OUT_ATTENDANCE_LEFT_KEY; 
						OutActions.put(outAttendanceKey, action);   //存储我开工的action
						outGo = true;
					}
					//normalActions.put(QDConstants.OUT_ATTENDANCE_LEFT_KEY, action);
					
				} else if (subType.equals(QDConstants.OUT_ATTENDANCE_RIGHT_KEY)) { //我收工
					if(outGo){
					// 外勤，我收工了
					if (outAttendanceKey.equals(QDConstants.OUT_ATTENDANCE_LEFT_KEY)) { //有我开工的状态          没有到了和走了的信息
						// 外勤数据成立
						companyAttendanceKey= "";
						validateActions = new ArrayList<Map<String, Actioninfo>>();
						normalActions =  new HashMap<String, Actioninfo>(); 
					}
						
					else if (outAttendanceKey.startsWith(QDConstants.OUT_ATTENDANCE_LEFT_KEY)
							&& outAttendanceKey.endsWith(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY)
							||
							outAttendanceKey.startsWith(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY)
							&& outAttendanceKey.endsWith(QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY)) {  //有我到了，和我走了 的状态				
                        //可能有完整 到 了 ，走了数据 ，也可能没有
						if(!tmpValidateAction.isEmpty()){
							//把到了和走了 整合插入中间表
							
							savelegworktimes(userId, tmpValidateAction);
						}
						companyAttendanceKey= "";
						validateActions = new ArrayList<Map<String, Actioninfo>>();
						normalActions =  new HashMap<String, Actioninfo>(); 

						// 清理
					} else if (outAttendanceKey.equals(QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY)){ //有完整的 到 了。 走了
					
						//把到了和走了 整合插入中间表
						//tmpValidateAction
						// 清理
						savelegworktimes(userId, tmpValidateAction);
						companyAttendanceKey= "";
						validateActions = new ArrayList<Map<String, Actioninfo>>();
						normalActions =  new HashMap<String, Actioninfo>(); 
					
					}
					}

				} else if (subType.equals(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY)) {   //到了 
					// 外勤，我到了
					if (outAttendanceKey.equals(QDConstants.OUT_ATTENDANCE_LEFT_KEY)) {  //有我开工的状态
						outAttendanceKey = outAttendanceKey.concat(".").concat(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY);
                        
						OutActions.put(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY, action); //把 到了的action 存入 OutActions
						//normalActions.put(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY, action);
					}
					
					if(outAttendanceKey.equals(QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY)){  //状态我 走了之后 的 有去了另外家公司（到了）
						outAttendanceKey = QDConstants.OUT_ATTENDANCE_LEFT_KEY;
                        outAttendanceKey = outAttendanceKey.concat(".").concat(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY);
						OutActions.put(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY, action); //把 到了的action 存入 OutActions
					}
					
					

				} else if (subType.equals(QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY)) {  //走了
					// 外勤，我走了
					if (outAttendanceKey.startsWith(QDConstants.OUT_ATTENDANCE_LEFT_KEY)
							&& outAttendanceKey.endsWith(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY)) {
						// 都需要保存
						outAttendanceKey = QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY; //走了
						Map<String, Actioninfo> tmpMaps = new HashMap<String, Actioninfo>();

						tmpMaps.put( QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY ,OutActions.get(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY)); //把暂存的到了的action 放入到tmpMaps
						
						tmpMaps.put(outAttendanceKey, action);  //存入走了的action
						tmpValidateAction.add(tmpMaps);
					}
					
					if(outAttendanceKey.equals(QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY)){
						outAttendanceKey = QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY;  //状态变成 走了
						if(tmpValidateAction.size()-1>-1){
							tmpValidateAction.get(tmpValidateAction.size()-1).put(outAttendanceKey, action); // 如果 有多个我走了，把最后的我走了 存入
						}
						
					}
				}
			}
		}         
		return null;
	}

	private void savelegworktimes(String userId,
			List<Map<String, Actioninfo>> validateActions) throws Exception {
		@SuppressWarnings("unchecked")
		List<companyGps> companys = getObjects(companyGps.class);
		// 参数
		double maxNester = 100l;

		for (Map<String, Actioninfo> actionData : validateActions) {
			// 与公司进行匹配
			for (Iterator<Entry<String, Actioninfo>> entrys = actionData.entrySet().iterator(); entrys.hasNext();) {
				Entry<String, Actioninfo> entry = entrys.next();
				if (entry.getKey().equals(QDConstants.OUT_ATTENDANCE_LEFT_SMALL_LEFT_KEY)
						|| entry.getKey().equals(QDConstants.OUT_ATTENDANCE_RIGHT_SMALL_RIGHT_KEY)) {
					// 判断最近
					Actioninfo action = entry.getValue();
					for (companyGps company : companys) {
						if (new BigDecimal(company.getLocLatitude()).subtract(new BigDecimal(entry.getValue().getLocLongtitude())).doubleValue() < maxNester) {
							if (new BigDecimal(company.getLocLatitude()).subtract(new BigDecimal(entry.getValue().getLocLatitude())).doubleValue() < maxNester) {
								// 真实
								save(new LegworkTimes().copyProperties(userId, actionData, company));
							}
						}
					}

				}
			}
		}
	}


}
